package com.serviportales.serviquality.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.springframework.stereotype.Repository;

import com.serviportales.serviportales.dao.GenericHibernateDAO;
import com.serviportales.serviportales.exceptions.DAOException;
import com.serviportales.serviportales.utils.BeansUtils;
import com.serviportales.serviquality.model.Proyecto;
import com.serviportales.serviquality.model.ProyectoUser;

@Repository
public class ProyectoUserDAO extends GenericHibernateDAO<ProyectoUser> {

	private static final long serialVersionUID = 1L;

	@Override
	public DetachedCriteria getBasicDetachedCriteria(ProyectoUser proyectoUser) throws DAOException {
		DetachedCriteria criteria = DetachedCriteria.forClass(ProyectoUser.class, "proyectoUser");
		try {
			Long userId = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.userId", Long.class);
			if (userId != null) {
				criteria.add(Restrictions.eq("proyectoUserPK.userId", userId));
			}

			String cdProyecto = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.codigo", String.class);
			String nombre = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.nombre", String.class);
			String cdEstadoProyecto = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.estadoRegistro.codigo", String.class);
			if (!BeansUtils.isEmpty(cdProyecto) || !BeansUtils.isEmpty(nombre) || !BeansUtils.isEmpty(cdEstadoProyecto)) {
				DetachedCriteria criteriaProyecto = DetachedCriteria.forClass(Proyecto.class);
				if (!BeansUtils.isEmpty(cdProyecto)) {
					criteriaProyecto = criteriaProyecto.add(Restrictions.ilike("codigo", cdProyecto));
				}

				if (!BeansUtils.isEmpty(nombre)) {
					criteriaProyecto = criteriaProyecto.add(Restrictions.ilike("nombre", nombre, MatchMode.ANYWHERE));
				}

				if (!BeansUtils.isEmpty(cdEstadoProyecto)) {
					criteriaProyecto = criteriaProyecto.add(Restrictions.eq("estadoRegistro.codigo", cdEstadoProyecto));
				}
				criteriaProyecto.setProjection(Projections.property("codigo"));
				criteria.add(Subqueries.propertyEqAll("proyectoUserPK.proyecto.codigo", criteriaProyecto));
			}

			String cdEstadoUserProyecto = BeansUtils.getDatoAtributo(proyectoUser, "estadoRegistro.codigo", String.class);
			if (!BeansUtils.isEmpty(cdEstadoUserProyecto)) {
				criteria.add(Restrictions.eq("estadoRegistro.codigo", cdEstadoUserProyecto));
			}
		} catch (Exception e) {
			throw new DAOException(e.getMessage(), e);
		}
		return criteria;
	}

	public ProyectoUser selectByID(Serializable codigo) {
		return getHibernateTemplate().get(ProyectoUser.class, codigo);
	}

	@SuppressWarnings("unchecked")
	public List<ProyectoUser> buscarProyectoUsersByUser(ProyectoUser proyectoUser) throws Exception {
		String strQuery = "from ProyectoUser as proyectoUser " + //
				"join fetch proyectoUser.proyectoUserPK.proyecto " + //
				"where proyectoUser.proyectoUserPK.userId = :userId " + //
				"and proyectoUser.estadoRegistro.codigo = :estadoRegistro ";

		String estadoRegistroProyecto = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.estadoRegistro.codigo", String.class);
		if (!BeansUtils.isEmpty(estadoRegistroProyecto)) {
			strQuery += "and proyectoUser.proyectoUserPK.proyecto.estadoRegistro.codigo = :estadoRegistroProyecto ";
		}
		String cdProyecto = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.codigo", String.class);
		if (!BeansUtils.isEmpty(cdProyecto)) {
			strQuery += "and upper(proyectoUser.proyectoUserPK.proyecto.codigo) like upper('%'||:cdProyecto||'%') ";
		}
		String nombreProyecto = BeansUtils.getDatoAtributo(proyectoUser, "proyectoUserPK.proyecto.nombre", String.class);
		if (!BeansUtils.isEmpty(nombreProyecto)) {
			strQuery += "and upper(proyectoUser.proyectoUserPK.proyecto.nombre) like upper('%'||:nombreProyecto||'%') ";
		}

		Query query = getSession().createQuery(strQuery);
		query.setLong("userId", proyectoUser.getProyectoUserPK().getUserId());
		query.setString("estadoRegistro", BeansUtils.getDatoAtributo(proyectoUser, "estadoRegistro.codigo", String.class));
		if (!BeansUtils.isEmpty(estadoRegistroProyecto)) {
			query.setString("estadoRegistroProyecto", estadoRegistroProyecto);
		}
		if (!BeansUtils.isEmpty(cdProyecto)) {
			query.setString("cdProyecto", cdProyecto);
		}
		if (!BeansUtils.isEmpty(nombreProyecto)) {
			query.setString("nombreProyecto", nombreProyecto);
		}
		return query.list();
	}
}
